﻿using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.Editors;
using DevExpress.ExpressApp.Layout;
using DevExpress.ExpressApp.Model;
using DevExpress.ExpressApp.Model.Core;
using DevExpress.ExpressApp.Model.NodeGenerators;
using DevExpress.ExpressApp.Utils;

namespace FeatureCenter.Module.Actions {
    public class CustomDetailViewLayoutGenarator : ModelNodesGeneratorUpdater<ModelDetailViewLayoutNodesGenerator> {

        public override void UpdateNode(ModelNode node) {
            if(node.Parent is IModelDetailView && ((IModelDetailView)(node.Parent)).ModelClass.TypeInfo.Implements<ICustomLayoutInfo>()) {
                IModelDetailView detailViewInfo = ((IModelDetailView)node.Parent);
                GenerateTabbedLayout(detailViewInfo);
            }
        }
        private void GenerateTabbedLayout(IModelDetailView detailViewInfo) {
            if(detailViewInfo.Layout["Main"] != null) {
                detailViewInfo.Layout["Main"].Remove();
            }
            IModelLayoutGroup main = detailViewInfo.Layout.AddNode<IModelLayoutGroup>(ModelDetailViewLayoutNodesGenerator.MainLayoutGroupName);
            IModelLayoutGroup generalNode = null;
            IModelTabbedGroup tabNode = null;
            IModelLayoutGroup footerNode = null;
            foreach(IModelPropertyEditor editor in detailViewInfo.Items) {
                if(FindModelDefaultAttribute(editor.ModelMember.MemberInfo, CustomDetailViewItemsGenarator.VisiblePropertiesAttribute) != null) {
                    editor.PropertyEditorType = typeof(DetailPropertyEditor);// editor.ModelMember.EditorsInfo[EditorAliases.DetailPropertyEditor].DefaultEditor;
                }
                editor.ImmediatePostData = true;
                IModelClassMemberExtender item = (IModelClassMemberExtender)editor;
                string tabPageName = item.TabPageName;
                if(string.IsNullOrEmpty(tabPageName)) {
                    if(item.Footer) {
                        if(footerNode == null) {
                            footerNode = main.AddNode<IModelLayoutGroup>(CustomDetailViewItemsGenarator.FooterId);
                            footerNode.Index = 5;
                        }
                        AddLayoutItemNode(footerNode, editor);
                    }
                    else {
                        if(generalNode == null) {
                            generalNode = main.AddNode<IModelLayoutGroup>(CustomDetailViewItemsGenarator.GeneralId);
                            generalNode.Index = editor.Index.HasValue ? editor.Index : 0;
                        }
                        AddLayoutItemNode(generalNode, editor);
                    }
                }
                else {
                    if(tabNode == null) {
                        tabNode = main.AddNode<IModelTabbedGroup>(CustomDetailViewItemsGenarator.MainTabId);
                        tabNode.Index = editor.Index.HasValue ? editor.Index : 1;
                    }
                    IModelLayoutGroup group = AddEditorToTabbedGroup(tabNode, tabPageName, editor);
                    if(editor.ModelMember.Index >= 0) {
                        group.Index = editor.ModelMember.Index;
                    }
                }
            }
        }
        private static ModelDefaultAttribute FindModelDefaultAttribute(IMemberInfo memberInfo, string attributeName) {
            foreach(ModelDefaultAttribute modelDefaultAttribute in memberInfo.FindAttributes<ModelDefaultAttribute>()) {
                if(modelDefaultAttribute.PropertyName == attributeName) {
                    return modelDefaultAttribute;
                }
            }
            return null;
        }
        private void AddLayoutItemNode(IModelLayoutGroup layoutGroup, IModelPropertyEditor editor) {
            IModelLayoutViewItem item = layoutGroup.AddNode<IModelLayoutViewItem>(editor.PropertyName);
            item.ViewItem = editor;
            item.Index = editor.Index;
        }
        private IModelLayoutGroup AddEditorToTabbedGroup(IModelTabbedGroup rootTabNode, string tabId, IModelPropertyEditor editor) {
            return AddEditorToTabbedGroup(rootTabNode, tabId, editor, FlowDirection.Horizontal);
        }
        private IModelLayoutGroup AddEditorToTabbedGroup(IModelTabbedGroup rootTabNode, string tabId, IModelPropertyEditor editor, FlowDirection direction) {
            IModelLayoutGroup rootTabPageNode = (IModelLayoutGroup)rootTabNode[tabId];
            if(rootTabPageNode == null) {
                rootTabPageNode = rootTabNode.AddNode<IModelLayoutGroup>(tabId);
                rootTabPageNode.Caption = CaptionHelper.ConvertCompoundName(tabId);
                rootTabPageNode.Direction = direction;
            }
            AddLayoutItemNode(rootTabPageNode, editor);
            return rootTabPageNode;
        }
    }
}
